package com.ficus.road.maintain.util.dingtalk;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ficus.road.maintain.core.model.dingtalk.*;
import com.ficus.road.maintain.core.model.dingtalk.message.DingTalkOpenMessage;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

/**
 * @author xiawen yang
 * @date 2022/2/17 下午4:20
 */
@Component
public class DingTalkUtil {

    private static final String DingTalkOpen_GetToken = "https://oapi.dingtalk.com/gettoken";
    private static final String DingTalkOpen_CorpMessageAsyncSend = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2";
    private static final String DingTalkOpen_GetUserInfo = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo";
    // 生产
//    private static final String APP_KEY = "dingnt5lsresjpltwxno";
//    private static final String APP_SECRET = "hbq2HRdWsMSyKU0K0voCmMOGI_TlgKrQN2btoU9ehSqrfD87QMrNZXv548p8JhUO";
//    private static final int AGENT_ID = 1299404478;
    // 测试
//    private static final String APP_KEY = "dingbhp974y92i06grvr";
//    private static final String APP_SECRET = "LjmzrK7r75YTQ_EK7kC0XGGDWN0Vjc4bbwC2OuT4w3CS3B5ek-6DWGiVwzY404Lq";
//    private static final int AGENT_ID = 1471781659;
    // 在过期前多久需要发起GetToken请求
    private static final int AccessTokenTimAvailOffset = 120;
    private static final RestTemplate restTemplate = new RestTemplate();
    private static long accessTokenTimestamp = -1;
    private static ObjectMapper objectMapper = new ObjectMapper();
    private static String TOKEN;
    private Map<String, String> params = new HashMap<>();
    @Value("${car_manager.app_key}")
    private String APP_KEY;
    @Value("${car_manager.app_secret}")
    private String APP_SECRET;
    @Value("${car_manager.agent_id}")
    private int AGENT_ID;

    @PostConstruct
    void init() {
        params.put("appkey", APP_KEY);
        params.put("appsecret", APP_SECRET);
    }

    // 获取登录token
    public String getToken() {
        if (System.currentTimeMillis() / 1000 > accessTokenTimestamp) {
            GetTokenResponse response = restTemplate.getForObject(DingTalkOpen_GetToken + "?appkey={appkey}&appsecret={appsecret}", GetTokenResponse.class, params);
            if (ObjectUtils.isNotEmpty(response)) {
                TOKEN = response.getAccessToken();
                accessTokenTimestamp = System.currentTimeMillis() / 1000 + response.getExpiresIn() - AccessTokenTimAvailOffset;
                return TOKEN;
            }
        }
        return TOKEN;
    }

    public DingTalkUserInfo getUserInfo(String authCode) throws Exception {
        String token = getToken();
        LinkedMultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
        queryParams.add("access_token", token);
        GetUserInfoRequest request = GetUserInfoRequest.builder().code(authCode).build();
        String json = objectMapper.writeValueAsString(request);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> httpEntity = new HttpEntity<>(json, httpHeaders);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(DingTalkOpen_GetUserInfo).queryParams(queryParams);
        String url = builder.toUriString();
        ResponseEntity<GetUserInfoResponse> userInfo = restTemplate.postForEntity(url, httpEntity, GetUserInfoResponse.class);
        if (userInfo.getBody().getErrCode() != 0) {
            throw new Exception(String.format("获取用户信息失败, authCode: %s, errCode: %s, errMsg: %s",
                    authCode,
                    userInfo.getBody().getErrCode(),
                    userInfo.getBody().getErrMsg()));
        }
        if (ObjectUtils.isNotEmpty(userInfo.getBody().getDingTalkUserInfo())) {
            return userInfo.getBody().getDingTalkUserInfo();
        }
        return null;
    }

    // 给指定的用户或部门发送钉钉消息
    public CorpMessageAsyncSendResponse corpMessageAsyncSend(List<String> userIds, List<String> deptIds, Boolean toAllUser, DingTalkOpenMessage message) throws Exception {
        String token = getToken();
        StringJoiner userIdJoiner = new StringJoiner(",");
        StringJoiner deptIdJoiner = new StringJoiner(",");
        if (ObjectUtils.isNotEmpty(userIds)) {
            userIds.forEach(userIdJoiner::add);
        }
        if (ObjectUtils.isNotEmpty(deptIds)) {
            deptIds.forEach(deptIdJoiner::add);
        }
        LinkedMultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
        queryParams.add("access_token", token);
        CorpMessageAsyncSendRequest request = CorpMessageAsyncSendRequest
                .builder()
                .agentId(AGENT_ID)
                .useridList(userIdJoiner.toString())
//                .deptIdList(deptIdJoiner.toString())
                .toAllUser(toAllUser)
                .msg(message)
                .build();
//        String body = JSON.toJSONString(request);
        String json = objectMapper.writeValueAsString(request);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> httpEntity = new HttpEntity<>(json, httpHeaders);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(DingTalkOpen_CorpMessageAsyncSend).queryParams(queryParams);
        String url = builder.toUriString();
//        CorpMessageAsyncSendResponse response = restTemplate.postForObject(DingTalkOpen_CorpMessageAsyncSend + "?access_token={access_token}", request, CorpMessageAsyncSendResponse.class, map);
        ResponseEntity<CorpMessageAsyncSendResponse> responseEntity = restTemplate.postForEntity(url, httpEntity, CorpMessageAsyncSendResponse.class);
        if (responseEntity.getBody().getErrCode() != 0) {
            throw new Exception(String.format("corpMessageAsyncSend方法失败, 错误码：%s, 错误信息: %s", responseEntity.getBody().getErrCode().toString(), responseEntity.getBody().getErrMsg()));
        }
        return responseEntity.getBody();
    }

    //    public static void main(String[] args) {
//        testMessageSend();
//    }
//
//    private static void testMessageSend() {
//        List<String> userIdList = Arrays.asList("226344426538097494");
//        DingTalkOpenMessage message = DingTalkOpenMessage
//                .builder()
//                .msgType("markdown")
//                .markDown(MarDownMessage.builder().title("车辆上线通知").text("# 车辆上线通知\n- 车牌：%s\n- 时间：%s\n").build()).build();
//        try {
//            corpMessageAsyncSend(userIdList, null, Boolean.FALSE, message);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    private static void testGetUserInfo() {
//
//    }
}
